#include "eString.hpp"

char eString::formatbuf[ESTRING_FORMAT_BUF_SIZE] = {0};
// const int eStringSize = sizeof(eString);
void * eString::operator new(std::size_t size) 
{
    /* Rewriting the new operation may result in
        null pointer access in the constructor */
    return eMalloc(size);
}
void eString::operator delete(void* ptr)
{
    if (ptr)
    {
        eFree(ptr);
    }
}
#pragma push
#pragma O0
eString::eString(void)
{
    if (NULL == this) return;
    this->pStr = NULL;
    this->len = 0;
    this->MemSize = 0;
}
eString::eString(const char *cstr)
{
    if (NULL == this) return;
    this->pStr = NULL;
    this->MemSize = 0;
    this->assign(cstr);
}
eString::eString(const eString& estr)
{
    if (NULL == this) return;
    this->pStr = NULL;
    this->MemSize = 0;
    this->assign(estr);
}
eString::eString(uint16_t length, char Char)
{
    volatile void* temp = NULL;
    if (this == temp) return;
    this->MemSize = length + 1;
    this->pStr = (char*)eMalloc(length);
    if (this->pStr == NULL)
    {
        this->MemSize = 0;
        this->len = 0;
        return;
    }
    std::memset(this->pStr, Char, length);
    this->len = length;
    this->pStr[this->len] = '\0';
}
eString::eString(uint16_t length)
{
    volatile void* temp = NULL;
    if (this == temp) return;
    this->MemSize = length + 1;
    this->pStr = (char*)eMalloc(length);
    if (this->pStr == NULL)
    {
        this->MemSize = 0;
    }
    this->len = 0;
}
#pragma pop
eString::~eString(void)
{
    if (this->pStr) eFree(this->pStr);
}

eStringState eString::assign(const char *cstr, uint16_t length)
{
    char *temp = NULL;
    eStringState ret = eSTRING_OK;
    if (this->MemSize < length + 1 || length < this->MemSize * 2)
    {
        temp = this->pStr;
        this->MemSize = length + 1;
        this->pStr = (char*)eMalloc(this->MemSize);
        if (this->pStr == NULL)
        {
            ret = eSTRING_ERROR;
            this->pStr = temp;
            goto exit;
        }
    }
    memcpy(this->pStr, cstr, length);
    this->len = length;
    this->pStr[this->len] = '\0';
    if (temp) eFree(temp);
    exit:
    return ret;
}
eStringState eString::assign(const char *cstr)
{
    uint16_t length = strlen(cstr);
    return this->assign(cstr, length);
}
eStringState eString::assign(const eString& estr)
{
    return this->assign((const char*)estr.pStr, estr.len);
}

eStringState eString::append(const char *cstr, uint16_t length)
{
    char *temp = NULL;
    if (length + this->len + 1 > this->MemSize)
    {
        temp = this->pStr;
        this->MemSize = length + this->len + 1;
        this->pStr = (char*)eMalloc(this->MemSize);
        if (this->pStr == NULL)
        {
            this->pStr = temp;
            return eSTRING_ERROR;
        }
        memcpy(this->pStr, temp, this->len);
    }
    memcpy(this->pStr + this->len, cstr, length);
    this->len += length;
    this->pStr[this->len] = '\0';
    if (temp) eFree(temp);
    return eSTRING_OK;
}
eStringState eString::append(const char *cstr)
{
    uint16_t length = strlen(cstr);
    return this->append(cstr, length);
}
eStringState eString::append(const eString& estr)
{
    return this->append(estr.pStr, estr.len);
}


eStringState eString::insert(uint16_t index, const char *cstr, uint16_t length)
{
    char *temp;
    if (index > this->len) return eSTRING_ERROR;
    temp = this->pStr;
    this->MemSize = length + this->len + 1;
    this->pStr = (char*)eMalloc(this->MemSize);
    if (this->pStr == NULL)
    {
        this->pStr = temp;
        return eSTRING_ERROR;
    }
    if (temp)
    {
        memcpy(this->pStr, temp, index);
        memcpy(this->pStr + index, cstr, length);
        memcpy(this->pStr + index + length, temp + index, this->len - index);
        eFree(temp);
    }
    else
    {
        memcpy(this->pStr, cstr, length);
    }
    this->len += length;
    this->pStr[this->len] = '\0';
    return eSTRING_OK;
}
eStringState eString::insert(uint16_t index, const char *cstr)
{
    return this->insert(index, cstr, strlen(cstr));
}
eStringState eString::insert(uint16_t index, const eString& estr)
{
    return this->insert(index, estr.pStr, estr.len);
}
eStringState eString::insert(uint16_t index, char Char)
{
    return this->insert(index, &Char, 1);
}

void eString::erase(uint16_t index, uint16_t length)
{
    if (this->len < index + length || this->MemSize == 0) return;
    memmove(this->pStr + index, this->pStr + index + length, this->len - index - length);
    this->len -= length;
    this->pStr[this->len] = '\0';
}

char eString::at(uint16_t index)
{
    if (index > this->len) return 0;
    return this->pStr[index];
}

uint16_t eString::mSize(void)
{
    return this->MemSize;
}

// 获取字符串长度
uint16_t eString::length(void) const
{
    return len;
}

// 判断字符串是否为空
bool eString::empty(void) const
{
    return len == 0;
}

// 清空字符串
void eString::clear(void)
{
    if (pStr)
    {
        eFree(pStr);
        pStr = NULL;
    }
    len     = 0;
    MemSize = 0;
}

// 获取字符串内容
const char *eString::c_str(void) const
{
    return pStr;
}
eString &eString::operator=(const eString &other)
{
    if (this == &other) return *this;
    this->assign(other.pStr, other.len);
    return *this;
}
eString &eString::operator=(const char *cstr)
{
    if (this->pStr == cstr) return *this;
    this->assign(cstr);
    return *this;
}

eString &eString::operator+=(const eString &estr)
{
    this->append(estr.pStr, estr.len);
    return *this;
}

eString &eString::operator+=(const char *cstr)
{
    this->append(cstr);
    return *this;
}

eString &eString::operator+=(char ch)
{
    this->append(&ch, 1);
    return *this;
}

// 连接字符串
eString eString::operator+(const char *cstr) const
{
    uint16_t length = strlen(cstr);
    uint16_t newLen = len + length;
    eString result(newLen);
    result.append(pStr, len);
    result.append(cstr, length);
    return result;
}
eString eString::operator+(const eString &other) const
{
    uint16_t newLen = len + other.len;
    eString result(newLen);
    result.append(pStr, len);
    result.append(other.pStr, other.len);
    return result;
}
eString eString::operator+(char Char) const
{
    uint16_t newLen = len + 1;
    char temp[2] = {Char, '\0'};
    eString result(newLen);
    result.append(pStr, len);
    result.append(temp, 1);
    return result;
}

char &eString::operator[](uint16_t index)
{
    if (index >= len)
    {
        // 处理越界情况，可以抛出异常或采取其他处理方式
        eString_LOG("index out of range\n");
    }
    return pStr[index];
}

const char &eString::operator[](uint16_t index) const
{
    if (index >= len)
    {
        // 处理越界情况，可以抛出异常或采取其他处理方式
        eString_LOG("index out of range\n");
    }
    return pStr[index];
}

// 比较字符串是否相等
bool eString::operator==(const eString &other) const
{
    return (len == other.len) && (std::strcmp(pStr, other.pStr) == 0);
}

// 比较字符串大小（字典序）
bool eString::operator<(const eString &other) const
{
    return std::strcmp(pStr, other.pStr) < 0;
}
bool eString::operator>(const eString &other) const
{
    return std::strcmp(pStr, other.pStr) > 0;
}

// 查找子字符串的第一次出现的位置
uint16_t eString::find(const char *substr) const
{
    const char *found = std::strstr(pStr, substr);
    if (found)
    {
        return static_cast<uint16_t>(found - pStr);
    }
    else
    {
        return npos; // 如果未找到，返回一个特定的无效位置标志
    }
}

// 查找子字符串的最后一次出现的位置
uint16_t eString::rfind(const eString& target) const
{
    const char* substr = target.pStr;
    const char* result = NULL;
    const char* current = pStr;
    while ((current = strstr(current, substr)) != NULL)
    {
        result = current;
        current++;
    }

    if (result != NULL)
    {
        return static_cast<uint16_t>(result - pStr);
    }
    return npos;
}

// 子字符串替换
eStringState eString::replace(const char *oldSubstr, const char *newSubstr)
{
    if (oldSubstr && newSubstr)
    {
        uint16_t oldLen = strlen(oldSubstr);
        uint16_t newLen = strlen(newSubstr);
        uint16_t pos    = find(oldSubstr);
        while (pos != npos)
        {
            erase(pos, oldLen);
            if (insert(pos, newSubstr, newLen) == eSTRING_ERROR)
            {
                return eSTRING_ERROR;
            }
            pos = find(oldSubstr);
        }
    }
    return eSTRING_OK;
}

// 子字符串计数
uint16_t eString::count(const char *substr) const
{
    uint16_t length = strlen(substr);
    uint16_t count = 0;
    if (!substr || length == 0)
    {
        return 0;
    }
    const char *pos = strstr(this->pStr, substr);
    while (pos != NULL)
    {
        count++;
        if (pos + length >= this->pStr + this->len) break;
        pos = strstr(pos+length, substr);
    }
    return count;
}

eStringState eString::zip(void)
{
    char *temp;
    if (this->len + 1 == this->MemSize) return eSTRING_ERROR;
    temp = this->pStr;
    this->MemSize = this->len + 1;
    this->pStr = (char*)eMalloc(this->MemSize);
    if (this->pStr == NULL)
    {
        this->pStr = temp;
        return eSTRING_ERROR;
    }
    memcpy(this->pStr, temp, this->len);
    this->pStr[this->len] = '\0';
    eFree(temp);
    return eSTRING_OK;
}

const char* eString::format(const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    std::vsnprintf(eString::formatbuf,
                   sizeof(eString::formatbuf),
                   format,
                   ap); // thread not safe
    return eString::formatbuf;
}
